//
// Created on 2024/5/16.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "pag_napi_matrix.h"
#include "napi/PagSurface.h"
#include "tgfx/core/Matrix.h"
#include "rendering/PAGAnimator.h"
#include <bits/alltypes.h>
#include <hilog/log.h>

namespace NativeXComponentSample {
    const int32_t STR_DEFAULT_SIZE = 2048;
    const int32_t INDEX_0 = 0;
    const int32_t INDEX_1 = 1;
    const int32_t INDEX_2 = 2;
    const int32_t INDEX_3 = 3;
    const int32_t PARAM_COUNT_1 = 1;
    const int32_t PARAM_COUNT_2 = 2;
    const int32_t PARAM_COUNT_3 = 3;
    const int32_t PARAM_COUNT_4 = 4;


    napi_ref PAGMatrix::sJSMatrixConstructor_ = nullptr;
    std::string PAGMatrix::_msg = "";
    const unsigned int LOG_PRINT_DOMAIN = 0XFF00;
    tgfx::Matrix g_pagMatrix = {};

    PAGMatrix::~PAGMatrix()
    {
        if (mRef != nullptr) {
            napi_delete_reference(mEnv, mRef);
        }
    };

    PAGMatrix::PAGMatrix(napi_env pEnv)
    {
        mEnv = pEnv;
    }

    PAGMatrix::PAGMatrix(napi_env pEnv, napi_ref pRef)
    {
        mEnv = pEnv;
        mRef = pRef;
    }
    void PAGMatrix::Destructor(napi_env env, void *nativeObject, void *finalize)
    {
        PAGMatrix *pagmatrix = reinterpret_cast<PAGMatrix *>(nativeObject);
        pagmatrix->PAGMatrix::~PAGMatrix();
    }

    napi_value PAGMatrix::JsMatrixConstructor(napi_env env, napi_callback_info info)
    {
        napi_value undefineVar = nullptr;
        napi_value thisVar = nullptr;
        napi_get_undefined(env, &undefineVar);

        if (napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr) == napi_ok && thisVar != nullptr) {
            // 创建NapiTest 实例
            PAGMatrix *reference = new PAGMatrix(env);
            // 绑定实例类创建NapiTest到导出的对象result
            if (napi_wrap(env, thisVar, reinterpret_cast<void *>(reference), PAGMatrix::Destructor, nullptr,
                          &(reference->mRef)) == napi_ok) {
                return thisVar;
            }

            return thisVar;
        }
        return undefineVar;
    }

    napi_value PAGMatrix::Setvalues(napi_env env, napi_callback_info info)
    {
        size_t argc = PARAM_COUNT_1;
        napi_value args[INDEX_1] = {nullptr};
        napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

        uint32_t result;
        napi_get_array_length(env, args[0], &result);
        float buffer[result];
        for (uint32_t i = 0; i < result; i++) {
            napi_value element;
            napi_get_element(env, args[0], i, &element);

            double value;
            napi_get_value_double(env, element, &value);
            float result = static_cast<float>(value);
            buffer[i] = result;
        }
        g_pagMatrix.set6(buffer);
        return nullptr;
    }

    napi_value PAGMatrix::GetScaleX(napi_env env, napi_callback_info info)
    {
        napi_value result;
        float num = g_pagMatrix.getScaleX();
        double value = static_cast<double>(num);
        napi_create_double(env, value, &result);
        return result;
    }

    napi_value PAGMatrix::GetScaleY(napi_env env, napi_callback_info info)
    {
        napi_value result;
        float num = g_pagMatrix.getScaleY();
        double value = static_cast<double>(num);
        napi_create_double(env, value, &result);
        return result;
    }

    napi_value PAGMatrix::GetSkewX(napi_env env, napi_callback_info info)
    {
        napi_value result;
        float num = g_pagMatrix.getSkewX();
        double value = static_cast<double>(num);
        napi_create_double(env, value, &result);
        return result;
    }

    napi_value PAGMatrix::GetSkewY(napi_env env, napi_callback_info info)
    {
        napi_value result;
        float num = g_pagMatrix.getSkewY();
        double value = static_cast<double>(num);
        napi_create_double(env, value, &result);
        return result;
    }

    napi_value PAGMatrix::GetTranslateX(napi_env env, napi_callback_info info)
    {
        napi_value result;
        float num = g_pagMatrix.getTranslateX();
        double value = static_cast<double>(num);
        napi_create_double(env, value, &result);
        return result;
    }

    napi_value PAGMatrix::GetTranslateY(napi_env env, napi_callback_info info)
    {
        napi_value result;
        float num = g_pagMatrix.getTranslateY();
        double value = static_cast<double>(num);
        napi_create_double(env, value, &result);
        return result;
    }

} // namespace NativeXComponentSample